#include "protocol_DragonBall.h"

//#define _MY_DEBUG 
#ifdef _MY_DEBUG 
//#define dbg_printf(fmt,x...) printf("%s,%d:"fmt,__FUNCTION__,__LINE__,##x)
#define dbg_printf(fmt,x...) printf(fmt,##x)
#else
#define  dbg_printf(fmt,x...)
#endif

namespace igslib
{
		
	Protocol_DragonBall::Protocol_DragonBall(){

        memset(Rxbuff,0,256);
        memset(Txbuff,0,256);

        Device[0] = std::bind(&Protocol_DragonBall::dev_gpio,this,std::placeholders::_1);
        Device[1] = std::bind(&Protocol_DragonBall::dev_acceptor,this,std::placeholders::_1);
        Device[2] = std::bind(&Protocol_DragonBall::dev_dispenser,this,std::placeholders::_1); 
        Device[3] = std::bind(&Protocol_DragonBall::dev_meter,this,std::placeholders::_1); 
        Device[4] = std::bind(&Protocol_DragonBall::dev_pwm,this,std::placeholders::_1); 
        Device[5] = std::bind(&Protocol_DragonBall::dev_vr,this,std::placeholders::_1);
		Device[6] = std::bind(&Protocol_DragonBall::dev_canbus,this,std::placeholders::_1);
        Device[7] = std::bind(&Protocol_DragonBall::dev_marquee,this,std::placeholders::_1);
        Device[8] = std::bind(&Protocol_DragonBall::dev_usart,this,std::placeholders::_1);
        Device[9] = std::bind(&Protocol_DragonBall::dev_IKV,this,std::placeholders::_1);
        Device[10] = std::bind(&Protocol_DragonBall::dev_dipswitch,this,std::placeholders::_1);
        Device[11] = std::bind(&Protocol_DragonBall::dev_battery,this,std::placeholders::_1);  	   
        ikv_dev.IsBusy=false;
        memset(input,0,gpin*sizeof(char));
	 }
	Protocol_DragonBall::~Protocol_DragonBall()
	{
		for(int i=0;i<canbuslen;i++)
		{

			for (std::map<int,CanReg_t*>::iterator it=reg_canbus[i].begin(); it!=reg_canbus[i].end(); ++it)
					delete it->second;
						
		}
	}		
		
	
	int Protocol_DragonBall::Update()
	{			
	  if(DelivBox.transferflg==true)  //transfor last package
	  {
		DelivBox.ISconnet=true;
		DelivBox.connect_cnt=0;
		DelivBox.transferflg=false;
		PrepareIO(&DelivBox,Txbuff);		
	  }
	  else
	  {
		if(++DelivBox.connect_cnt>125) //16ms*125=2s
			DelivBox.ISconnet=false;
	  }		    
	 FullDuplexReadWrite(Txbuff,Rxbuff,256);

#ifdef _MY_DEBUG 
        util::Log("TX:");
        for(int i=0;i<200;i++)
        {
            util::Log("%02x ",Txbuff[i]);
        }
        util::Log("\n");

        util::Log("RX:");
        for(int i=0;i<200;i++)
        {
            util::Log("%02x ",Rxbuff[i]);
        }
        util::Log("\n");
#endif	
        // }
        //if(Rxbuff[3]==0x2)
        // {
        // #ifdef _MY_DEBUG 
        // printf("TX:");
        // for(int i=0;i<64;i++)
        // printf("%02x ",Txbuff[i]);
        // printf("\n");

        // printf("RX:");
        // for(int i=0;i<64;i++)
        // printf("%02x ",Rxbuff[i]);
        // printf("\n");
        // #endif	
        // }
		 ProcessPn(&DelivBox, Rxbuff);
	}
    void Protocol_DragonBall::PrepareIO(box_t* pptr, char *buf)
    {
        int pkage_maxlen=252;
        unsigned char pkage_idx=3;	
        memset(buf,0,256);		
        while(!TxQueue.empty())
        {		
            IPacket* Dpacket=TxQueue.front(); 
            auto Dbuf = Dpacket->GetData();

            int DataLen=Dpacket->GetData().size();
            int PacetLen=DataLen+3;	

            if(PacetLen <= pkage_maxlen)
            {			   

                buf[pkage_idx++]=Dpacket->GetHeaderID();				   
                buf[pkage_idx++]=DataLen;
                for(int i=0; i<DataLen;i++)
                    buf[pkage_idx+i]=Dbuf[i];
                pkage_idx+=DataLen;
                buf[pkage_idx++]=Dpacket->GetSelfu8Checksum();

                DelivBox.count++;
                pkage_maxlen-=PacetLen;
                TxQueue.pop();
            }
            else
                break;
        }

        buf[0] = pptr->startflg; 		
        buf[1] = pptr->curPN;
        buf[2] = pptr->count;
        buf[255]=u8checksum(buf,255);

    }

    void Protocol_DragonBall::ProcessPn(box_t* io, char *buf)
    {
        unsigned char PN =(buf[1]&0x7f);		
        if(buf[1]==0x80)
        {
            io->curPN = 2;
            io->lastPN = 1;
            io->transferflg=true; 
        }
        else if ( ((io->lastPN &0x7f) == PN) && (buf[0] == 0x52) ) 
        {

            io->count=0;
            //checke pn mumber	
            io->lastPN=io->curPN;
            io->curPN++;
            if (io->curPN == 128) 
                io->curPN = 1;
            io->transferflg=true; 

            unsigned char RxCMDcnt=buf[2];
            unsigned char RxCMDstart=3;
            unsigned char RxCMDlen=4;

            while(RxCMDcnt)
            {				

                std::vector<char>Din;
                Din.clear();


                //擷取DATA部分		
                for(int i=0;i<buf[RxCMDlen];i++)
                    Din.push_back(buf[RxCMDstart+2+i]);	
                Device[(buf[RxCMDstart]-1)](Din);	
                RxCMDstart+=(buf[RxCMDlen]+3);//下一筆命令的HeaderId
                RxCMDlen+=(buf[RxCMDlen]+3);//下一筆命令的DataLength
                RxCMDcnt--;

            }			
        }	
    }

    unsigned char Protocol_DragonBall::u8checksum(char *ptr,int len)
    {
        unsigned char cksum=0;

        for(int i=0;i<len;i++)
        {
            cksum+=(unsigned char)*(ptr+i);
        }
        return cksum;
    }

    void Protocol_DragonBall::short_to_bytes(unsigned short a0 ,unsigned char* a1)
    {			
        *a1++ = a0 & 0xff;
        *a1++ = (a0 >> 8) & 0xff;			
    }

    /**************Device CMD list**************************************/	
    void Protocol_DragonBall::dev_IKV( std::vector<char> data)
    {		
        switch(data[0])
        {
            case 0:			
                ikv_dev.info.PID=(data[2]<<8)|data[1];
                ikv_dev.info.VIP=(data[4]<<8)|data[3];

                memcpy(&ikv_dev.info.CHIPID,&data[5],IKV_t::chipidLen);	
                memcpy(&ikv_dev.info.ODC,&data[5+IKV_t::chipidLen],IKV_t::odcLen);			
                ikv_dev.info.Dlock=data[97];							
                ikv_dev.IsBusy=false;
                break;

            case 1:			 
                memcpy(&ikv_dev.auth.RESP,&data[1],IKV_t::respLen);			
                memcpy(&ikv_dev.auth.MAC,&data[1+IKV_t::respLen],IKV_t::macLen);	
                ikv_dev.IsBusy=false;
                break;
            case 3:			 
                ikv_dev.ROMData.address=data[1];
                memcpy(&ikv_dev.ROMData.Data,&data[2],IKV_t::dataLen);	
                ikv_dev.IsBusy=false;
                break;	
            case 5:	 		 
                ikv_dev.IsBusy=false;
                break;
        }			
    }

    void Protocol_DragonBall::dev_gpio( std::vector<char> data)
    {	
        memcpy( input,&data[0],gpin);
    }

    void Protocol_DragonBall::dev_acceptor( std::vector<char> data)
    {			
        unsigned char sel=data[1];	

        if(data[0]==0x1) //detect coin cmd
        {		
            reg_coin[sel].nv+=data[2];
            reg_coin[sel].st=data[3];
        }
    }
    void Protocol_DragonBall::dev_dispenser( std::vector<char> data)
    {			
        unsigned char sel=data[1];	
        if(data[0]==0x1)
        {		
            reg_dispenser[sel].nv+=data[2];
            reg_dispenser[sel].st=data[3];
        }
    }
    void Protocol_DragonBall::dev_meter( std::vector<char> data){}
    void Protocol_DragonBall::dev_pwm( std::vector<char> data){}
	void Protocol_DragonBall::dev_marquee( std::vector<char> data){}
    void Protocol_DragonBall::dev_vr( std::vector<char> data)
    {	
        unsigned char sel=data[1];	
        if(data[0]==0x1) //detect 
        {		
            reg_vr[sel].absnv=(data[3]<<8|data[2]);
            reg_vr[sel].relanv=(int)data[4];
        }
    }
	
     void Protocol_DragonBall::dev_canbus( std::vector<char> data)
    {	
        unsigned char mID=data[1];
		unsigned char sID=data[2];
				
        if(data[0]==0x1) //detect  cmd
        {		     	    	
			reg_canbus[mID][sID]->valid=1;
			memcpy(&reg_canbus[mID][sID]->nv,&data[3],8);
        }
    }

	 void Protocol_DragonBall::dev_usart( std::vector<char> data)
    {	
        unsigned char sel=data[1];	
        if(data[0]==0x1) //detect coin cmd
        {		     	    
			 if(data[2]==1)
				reg_usart[sel].st=usat::busy;
			else if(data[2]==2)
				reg_usart[sel].st=usat::invalid;
			else if(data[2]==3)
				reg_usart[sel].st=usat::error;
			else
			{
				reg_usart[sel].st=usat::valid;
				memcpy(&reg_usart[sel].nv,&data[3],reg_usart[sel].len);		  //不確定len == 0 ok?
			}		
        }
    }
	
	void Protocol_DragonBall::dev_dipswitch( std::vector<char> data)
	{
		unsigned char sel=data[1];	
        if(data[0]==0x1) //detect coin cmd
		reg_dipswitch[sel]=data[2];
	}
	
	void Protocol_DragonBall::dev_battery( std::vector<char> data)
	{
		unsigned char sel=data[1];	
        if(data[0]==0x1) 
		reg_battery[sel]=data[2];
  
	}

    /****************IKV Function*********************/
    bool  Protocol_DragonBall::ikv_IsBusy()
    {			
        return ikv_dev.IsBusy;
    }

    int Protocol_DragonBall::ikv_GetInfo(unsigned char* bkval)
    {			
        int retlen=0;

        short_to_bytes(ikv_dev.info.PID,bkval);
        bkval+=2;
        retlen+=2;

        short_to_bytes(ikv_dev.info.VIP,bkval);
        bkval+=2;
        retlen+=2;

        memcpy(bkval,&ikv_dev.info.CHIPID,IKV_t::chipidLen);	
        bkval+=IKV_t::chipidLen;

        memcpy(bkval,&ikv_dev.info.ODC,IKV_t::odcLen);	
        bkval+=IKV_t::odcLen;

        *bkval++ = ikv_dev.info.Dlock;		
        retlen++;

        return retlen;
    }

    int Protocol_DragonBall::ikv_GetResponse(unsigned char* bkval)
    {			
        int retlen=0;

        memcpy(bkval,&ikv_dev.auth.RESP,IKV_t::respLen);	
        bkval+=IKV_t::respLen;

        memcpy(bkval,&ikv_dev.auth.MAC,IKV_t::macLen);	
        bkval+=IKV_t::macLen;

        return retlen;
    }

    int Protocol_DragonBall::ikv_GetROMData(unsigned char* bkval)
    {			
        memcpy(bkval,&ikv_dev.ROMData.Data,IKV_t::dataLen);	
        return (sizeof(IKV_t::ROMData_t));
    }

    void Protocol_DragonBall::ikv_Setup()
    {					
        const char raw[] = 
        {
            0xA,  // header
            2,    // length
            0,	  // ikv_cmd	
            1,    // data
        };  
        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();

        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);

        ikv_dev.IsBusy=true;		
    }

    void Protocol_DragonBall::ikv_SetROMData(int addr,char *data)
    {				  
        char raw[20] = 
        {
            0xA,  // header
            18,    // length
            2,	  // ikv_cmd	
        };  

        raw[3]=addr;
        memcpy(&raw[4],data,IKV_t::dataLen);	

        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);				
        ikv_dev.IsBusy=true;

    }

    void Protocol_DragonBall::ikv_SetROMaddr(int addr)
    {				  
        char raw[4] = 
        {
            0xA,  // header
            2,    // length
            3,	  // ikv_cmd	
        };  
        raw[3]=addr;

        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);				
        ikv_dev.IsBusy=true;
    }

    void Protocol_DragonBall::ikv_SetChallenge(unsigned char *data)
    {			
        char raw[25] = 
        {
            0xA,  // header
            23,    // length
            1,	  // ikv_cmd	
        };  

        memcpy(&raw[3],data,IKV_t::challengeLen);	

        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);				
        ikv_dev.IsBusy=true;

    }

    void Protocol_DragonBall::ikv_DLock()
    {			
        char raw[3] = 
        {
            0xA,  // header
            1,    // length
            4,	  // ikv_cmd	
        };  	
        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);				
        ikv_dev.IsBusy=true;
    }

    /******GPIO Function*********/
    void Protocol_DragonBall::SetGPout(char pin , char lv)
    {
        char raw[4] = 
        {
            0x1,  // header
            2,    // length
        }; 
        raw[2]=pin;
        raw[3]=lv;
        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);				
    }

    int Protocol_DragonBall::GetGPin(char *lv)
    {
        memcpy(lv,input,gpin);
        return inblen;		
    }

    /******acceptor Function*********/
    int  Protocol_DragonBall::GetAcceptorNV(char ID)
    {
        int rtn = 0;
        if(ID>inPinSw)
        {
            util::Log("Protocol_DragonBall::GetAcceptorNV ID is over");
            return rtn;
        }
        rtn=reg_coin[ID].nv;
        reg_coin[ID].nv=0;
        return rtn;
    }
    int  Protocol_DragonBall::GetAcceptorSat(char ID)
    {
        int rtn = 0;
        if(ID>inPinSw)
        {
            util::Log("Protocol_DragonBall::GetAcceptorSat ID is over");
            return rtn;
        }
        rtn = reg_coin[ID].st;
        return rtn;
    }
    void Protocol_DragonBall::SetupAcceptor(char ID, char* AccData)
    {
        char raw[11] = 
        {
            0x2,  // header
            9,    // length
            0,    //coin cmd
        }; 
        raw[3]=ID;
        memcpy(&raw[4],AccData,7);	
        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);		
    }
    int Protocol_DragonBall::SetAcceptor(char ID, char data, const std::string& func)
    {
        int rtn = 0;
        char raw[6] = {0};
        raw[0] = 0x2; // header
        raw[1] = 4;   // length
        raw[2] = 1;   //coin cmd	
        raw[3]=ID;

        if(func == "ClrE")	
        {
            raw[4]=data;
        }
        else if(func == "Inhibit")	
        {
            raw[5]=data;
        }
        else		
        {
            rtn = -1;
            util::Log("Protocol_DragonBall::SetAcceptor CMD fail");
            return rtn;
        }

        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);		
        return rtn;
    }

    /******dispenser Function*********/
    int  Protocol_DragonBall::GetDispenserNV(char ID)
    {
        int rtn = 0;
        if(ID>inPinSw)
        {
            rtn = -1;
            util::Log("Protocol_DragonBall::GetDispenserNV ID is over");
            return rtn;
        }
        rtn=reg_dispenser[ID].nv;
        reg_dispenser[ID].nv=0;
        return rtn;
    }

    int  Protocol_DragonBall::GetDispenserSat(char ID)
    {
        int rtn = 0;
        if(ID>inPinSw)
        {
            rtn = -1;
            util::Log("Protocol_DragonBall::GetAcceptorSat ID is over");
            return rtn;
        }
        rtn = reg_dispenser[ID].st;	
        return rtn;
    }
    void Protocol_DragonBall::SetupDispenser(char ID, char* DispData)
    {
        char raw[21] = 
        {
            0x3,  // header
            19,    // length
            0,    //coin cmd
        }; 
        raw[3]=ID;
        memcpy(&raw[4],DispData,17);	
        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);	

    }
    /*@param a2 --Rest --PayOut */
    int Protocol_DragonBall::SetDispenser(char ID, int data, const std::string& func)
    {	
        int rtn = 0;
        char raw[7] = {0};
        raw[0] = 0x3; // header
        raw[1] = 5;   // length
        raw[2] = 1;   //coin cmd	
        raw[3]=ID;

        if(func == "Rest")	
        {
            raw[6]=data;
        }
        else if(func == "PayOut")	
        {
            raw[4]=(char)data;
            raw[5]=(char)(data>>8);
        }
        else		
        {
            rtn = -1;
            util::Log("Protocol_DragonBall::SetDispenser CMD fail");
            return rtn;
        }

        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);			
        return rtn;
    }
    /******Meter Function*********/
    void Protocol_DragonBall::SetupMeter(char ID, char* mtdata)
    {
        char raw[11] = 
        {
            0x4,  // header
            9,    // length
            0,    //cmd
        }; 
        raw[3]=ID;
        memcpy(&raw[4],mtdata,7);
        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);			
    }
    void Protocol_DragonBall::SetMeter(char ID, short val)
    {
        char raw[6] = {0};
        raw[0]=0x4;// header
        raw[1]=4;	// length
        raw[2]=1;		//cmd	
        raw[3]=ID;
        raw[4]=val;
        raw[5]=val/256;

        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);		
    }
    char Protocol_DragonBall::GetMeterNV(char ID)
    {
        auto tmp=reg_meter[ID];
        reg_meter[ID]=0;
        return tmp;
    }

    /******PWM Function*********/
    void Protocol_DragonBall::SetupPWM(char ID, char* pwndata)
    {
        char raw[6] = 
        {
            0x5,  // header
            4,    // length
            0,    //cmd
        }; 
        raw[3]=ID;
        memcpy(&raw[4],pwndata,2);
        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);

		// printf("Setup:%02x ",raw[0]);
		// for(int i=1;i<6;i++)
		// printf("%02x ",raw[i]);
		// printf("\n");
		
    }
    void Protocol_DragonBall::SetPWM(char ID, char val)
    {
        char raw[5] = {0};
        raw[0]=0x5;// header
        raw[1]=3;	// length
        raw[2]=1;		//cmd	
        raw[3]=ID;
        raw[4]=255*((100-val)/100);
        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);	
    }

    /******VR Function*********/
    int  Protocol_DragonBall::GetVRabs(char ID,float* result)
    {
        int rtn = 0;
        if(ID>inPinSw/2)
        {
            rtn = -1;
            util::Log("Protocol_DragonBall::GetVRabs ID is over");
            return rtn;
        }
        *result = reg_vr[ID].absnv;
        return rtn;
    }
    int  Protocol_DragonBall::GetVRrela(char ID,float* result)
    {
        int rtn = 0;
        if(ID>inPinSw/2)
        {
            rtn = -1;
            util::Log("Protocol_DragonBall::GetVRrela ID is over");
            return rtn;
        }
        *result = reg_vr[ID].relanv;
        return rtn;
    }
    void Protocol_DragonBall::SetupVR(char ID, char val)
    {
        char raw[5] = 
        {
            0x6,  // header
            3,    // length
            0, 
        }; 
        raw[3]=ID;
        raw[4]=val;	
        IPacketManager* mgr = GetPacketManagerInstance();
        IPacket* packet = mgr->NewPacket();		
        int import_result = packet->ImportRawData(raw);
        TxQueue.push(packet);		
    }
	
	/******CanBus Function*********/
	
	void Protocol_DragonBall::FlushCanbus(char ID,char sID)
	{
		for(int i=0;i<8;i++)		
		reg_canbus[ID][sID]->nv[i]=0;

		reg_canbus[ID][sID]->valid=1;
	}
	
	
	int  Protocol_DragonBall::GetCanbusNV(char ID, char sID, char * candata)
	{	
	
		if(reg_canbus[ID][sID]->valid)
		{
					
			memcpy(candata,&reg_canbus[ID][sID]->nv,8);
			reg_canbus[ID][sID]->valid=0;
			return 8;
		
		}
		reg_canbus[ID][sID]->valid=0;
		return -1;		
	}

	void Protocol_DragonBall::SetCanbus(char ID, char tID,char* candata)
	{
		char raw[13] = 
		{
			0x7,  // header
			11,    // length
			1, 
		}; 
		raw[3]=ID;
		raw[4]=tID;
		
		memcpy(&raw[5],candata,8);
		
		IPacketManager* mgr = GetPacketManagerInstance();
		IPacket* packet = mgr->NewPacket();		
		int import_result = packet->ImportRawData(raw);
		TxQueue.push(packet);
		reg_canbus[ID][tID] = new CanReg_t();			
	
	}
	void Protocol_DragonBall::SetupCanbus(char ID, char* candata)
	{
		char raw[6] = 
		{
			0x7,  // header
			4,    // length
			0, 
		}; 
		raw[3]=ID;
		raw[4]=candata[0];
		raw[5]=candata[1];
		IPacketManager* mgr = GetPacketManagerInstance();
		IPacket* packet = mgr->NewPacket();		
		int import_result = packet->ImportRawData(raw);
		TxQueue.push(packet);		
	}	
		
    /******lamp Function*********/
	void Protocol_DragonBall::LoadGroup(char ID,int len,char* marqdata)
	{
			char raw[len+4];	
			raw[0]=0x8;
			raw[1]=len+2;
			raw[2]=0x3;
			raw[3]=ID;
			memcpy(&raw[4],marqdata,len);
			IPacketManager* mgr = GetPacketManagerInstance();
			IPacket* packet = mgr->NewPacket();		
			int import_result = packet->ImportRawData(raw);
			TxQueue.push(packet);	
	}
	void Protocol_DragonBall::LoadPattern(char ID,int len, char* marqdata )
	{
		
		char raw[len+4];	
		raw[0]=0x8;
		raw[1]=len+2;
		raw[2]=0x2;
		raw[3]=ID;
		memcpy(&raw[4],marqdata,len);
		IPacketManager* mgr = GetPacketManagerInstance();
		IPacket* packet = mgr->NewPacket();		
		int import_result = packet->ImportRawData(raw);
		TxQueue.push(packet);	
	
	}
	void Protocol_DragonBall::SetMarquee(char ID, char* marqdata)
	{
		char raw[7] = 
		{
			0x8,  // header
			5,    // length
			1, 
		}; 
		raw[3]=ID;
		memcpy(&raw[4],marqdata,3);
		IPacketManager* mgr = GetPacketManagerInstance();
		IPacket* packet = mgr->NewPacket();		
		int import_result = packet->ImportRawData(raw);
		TxQueue.push(packet);	
	
	}
	void Protocol_DragonBall::SetupMarquee(char ID, char* marqdata)
	{		
		char raw[8] = 
		{
			0x8,  // header
			6,    // length
			0, 
		}; 
		raw[3]=ID;
		memcpy(&raw[4],marqdata,4);
		IPacketManager* mgr = GetPacketManagerInstance();
		IPacket* packet = mgr->NewPacket();		
		int import_result = packet->ImportRawData(raw);
		TxQueue.push(packet);	
	}

	/******USART Function*********/
	void Protocol_DragonBall::FlushUsart(char ID)
	{
		for(int i=0;i<reg_usart[ID].len;i++)		
		reg_usart[ID].nv[i]=0;
	
		if(reg_usart[ID].st==usat::invalid)
		 reg_usart[ID].st=usat::valid;
	}
	int Protocol_DragonBall::GetUsartNV(char ID,char * usdata)
	{	
		memcpy(usdata,&reg_usart[ID].nv,reg_usart[ID].len);			
		return reg_usart[ID].len;
	}
	int Protocol_DragonBall::GetUsartSat(char ID)
	{		
		return reg_usart[ID].st;
	}
	void Protocol_DragonBall::SetUsart(char ID,int len, char* usdata)
	{
		char raw[len+3] ;
		raw[0]=0x9;
		raw[1]=len+2;
		raw[2]=1;
		raw[3]=ID;
		memcpy(&raw[4],usdata,len);
		IPacketManager* mgr = GetPacketManagerInstance();
		IPacket* packet = mgr->NewPacket();		
		int import_result = packet->ImportRawData(raw);
		TxQueue.push(packet);
		if(reg_usart[ID].SM == 0)
		reg_usart[ID].st=usat::busy;

	}
	void Protocol_DragonBall::SetupUsart(char ID, char* usdata)
	{				
		char raw[14] = 
		{
			0x9,  // header
			12,    // length
			0, 
		}; 
		raw[3]=ID;
		memcpy(&raw[4],usdata,10);
		IPacketManager* mgr = GetPacketManagerInstance();
		IPacket* packet = mgr->NewPacket();		
		int import_result = packet->ImportRawData(raw);
		TxQueue.push(packet);			
		reg_usart[ID].len=usdata[2];
		reg_usart[ID].st=usat::valid;
		reg_usart[ID].SM=usdata[9];  //master/slave		
	}	

	/******DipSwitch Function*********/
		char Protocol_DragonBall::GetDipSwitchNV(char ID)
		{
			return reg_dipswitch[ID];
		}
		void Protocol_DragonBall::SetupDipSwitch(char ID, char val)
		{		
			char raw[5] = 
			{
				11,  // header
				3,    // length
				0, 
			}; 
			raw[3]=ID;
			raw[4]=val;	
			IPacketManager* mgr = GetPacketManagerInstance();
			IPacket* packet = mgr->NewPacket();		
			int import_result = packet->ImportRawData(raw);
			TxQueue.push(packet);			
		}

			
	/******Battery Function*********/
		char Protocol_DragonBall::GetBatteryNV(char ID)
		{			
		  return reg_battery[ID];		
		}
		void Protocol_DragonBall::SetupBattery(char ID, char val)				
		{
			char raw[5] = 
			{
				12,  // header
				3,    // length
				0, 
			}; 
			raw[3]=ID;
			raw[4]=val;	
			IPacketManager* mgr = GetPacketManagerInstance();
			IPacket* packet = mgr->NewPacket();		
			int import_result = packet->ImportRawData(raw);
			TxQueue.push(packet);	
		}
	
};

